﻿using CommunityToolkit.Mvvm.ComponentModel;
using CommunityToolkit.Mvvm.Input;
using FinalPointSet.Model.Constant;
using FinalPointSet.Model.Constant.Message;
using FinalPointSet.Model.Constants;
using FinalPointSet.Model.Manager;
using FinalPointSet.Model.Model.Knowledge;
using FinalPointSet.Model.Util;
using FinalPointSet.View;
using ICSharpCode.AvalonEdit.Highlighting;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Windows;

namespace FinalPointSet.ViewModel
{
    /// <summary>
    /// 搜索页面ViewModel
    /// </summary>
    public partial class SearchViewModel : ObservableObject
    {
        #region 属性变量
        /// <summary>
        /// 窗体高度
        /// </summary>
        [ObservableProperty]
        private int _windowHeight = Config.SearchWindow_KeywordSearching_Height;
        /// <summary>
        /// 知识点
        /// </summary>
        [ObservableProperty]
        private List<KnowledgePoint>? _knowledgePoints;
        /// <summary>
        /// 匹配的知识点
        /// </summary>
        [ObservableProperty]
        private List<KnowledgePoint> _matchKnowledgePoints = [];
        /// <summary>
        /// 语言
        /// </summary>
        [ObservableProperty]
        private List<Language>? _languages;
        /// <summary>
        /// 搜索的关键词
        /// </summary>
        [ObservableProperty]
        private string _searchWord = "";
        /// <summary>
        /// 选中的知识点
        /// </summary>
        [ObservableProperty]
        private KnowledgePoint? _selectedKnowledgePoint;
        /// <summary>
        /// 高亮样式
        /// </summary>
        [ObservableProperty]
        private IHighlightingDefinition? _highlightingDefinition;
        /// <summary>
        /// 关键词匹配权重价值
        /// </summary>
        private KeywordMatchWorth? KeywordMatchWorth { get; set; } = new();
        private readonly Stopwatch stopwatch = new();
        private TimeSpan lastSearchTime;
        private const double MinIntervalSeconds = 0.15;
        //两次搜索间隔在1小时, 则重新加载一次数据
        private TimeSpan lastInitTime;
        private const double ReInitKPIntervalSeconds = 3600;
        #endregion

        public SearchViewModel()
        {
            InitResource();
            //监听数据源集合资源变化
            AssetManager.Instance.OnJsonObjectListUpdate += OnResourceUpdate;
            stopwatch.Start();
            lastInitTime = stopwatch.Elapsed;
        }

        /// <summary>
        /// 重新初始化资源
        /// </summary>
        /// <param name="type"></param>
        private void OnResourceUpdate(Type type)
        {
            if (type == typeof(KnowledgePoint) || type == typeof(CustomParam))
                Debug.Print($"SearchViewModel.OnResourceUpdate(), Type={type.Name}");

            InitResource();
        }

        /// <summary>
        /// 初始化资源
        /// </summary>
        private void InitResource()
        {
            SelectedKnowledgePoint = null;
            MatchKnowledgePoints.Clear();
            List<KnowledgePoint> kps = AssetManager.Instance.GetJsonObjectList<KnowledgePoint>();
            KnowledgePoints = new(kps.Count);
            foreach (KnowledgePoint item in kps)
            {
                KnowledgePoints.Add(KnowledgePoint.Clone(item));
            }
            KeywordMatchWorth = AssetManager.Instance.GetJsonObject<KeywordMatchWorth>();
        }

        /// <summary>
        /// 搜索关键词
        /// </summary>
        [RelayCommand]
        private void Search()
        {
            if (KnowledgePoints is null)
                return;
            double elapsedSeconds = (stopwatch.Elapsed - lastSearchTime).TotalSeconds;
            double initDuration = (stopwatch.Elapsed - lastInitTime).TotalSeconds;
            //检测两次搜索时间是否超过阈值,超过则进行搜索
            if (initDuration > ReInitKPIntervalSeconds)
            {
                Debug.Print($"SearchViewModel.Search(), 超过阈值:{ReInitKPIntervalSeconds}秒,重新加载知识点资源");
                InitResource();
                lastInitTime = stopwatch.Elapsed;
            }
            //检测两次搜索时间是否超过阈值,超过则进行搜索
            if (elapsedSeconds < MinIntervalSeconds)
            {
                Debug.Print($"SearchViewModel.Search(), 搜索的关键词:{SearchWord}, 当前搜索间隔过短, 直接退出搜索");
                return;
            }
            else
            {
                Debug.Print($"SearchViewModel.Search(), 搜索的关键词:{SearchWord}, 当前搜索间隔 > {MinIntervalSeconds}, 开始搜索结果");
            }

            try
            {
                //匹配搜索的关键词
                MatchKnowledgePoints = KnowledgePointHelper.GetMatchKnowledgePoints(KnowledgePoints, KeywordMatchWorth, SearchWord);
                Dictionary<string, string> customParamDict = CustomParamHelper.GenerateCustomParams();
                foreach (KnowledgePoint item in MatchKnowledgePoints)
                {
                    foreach (string key in customParamDict.Keys)
                    {
                        item.Content = item.Content.Replace(key, customParamDict[key]);
                    }
                }
            }
            catch (Exception e)
            {
                MessageManager.Broadcast(MsgType.GrowMsg, new GrowMsgArg(WindowType.SearchView, GrowlMsgType.Error, $"搜索关键词异常! 异常原因: {e.Message}"));
            }

            lastSearchTime = stopwatch.Elapsed;
        }

        [RelayCommand]
        private static void LogoButtonClick()
        {
            Debug.Print("SearchViewModel.LogoButtonClick(),按下图标按钮");
            WindowUtil.Instance.Show(typeof(MainView), Location.Center, ScaleMode.Auto);
        }

        [RelayCommand]
        private void SelectedKnowledgeChange()
        {
            Debug.Print("SearchViewModel.SelectedChange(),选中变更");
            if (SelectedKnowledgePoint != null && !string.IsNullOrEmpty(SelectedKnowledgePoint.Content))
            {
                try
                {
                    Clipboard.SetText(SelectedKnowledgePoint.Content);
                }
                catch (Exception e)
                {
                    Debug.Print($"SearchViewModel.SelectedChange(),复制文本到粘贴板失败!,失败原因:{e.Message}");
                }
            }
        }

        public void Dispose()
        {
            AssetManager.Instance.OnJsonObjectListUpdate -= OnResourceUpdate;
        }
    }
}
